﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public static class GetComponentsExtensions
{
	public static List<Material> GetSharedMaterialsEx(this Renderer render)
	{
		List<Material> l = UnityListPool<Material>.Create();
		render.GetSharedMaterials(l);
		return l;
	}

	public static void SetSharedMaterialsEx(this Renderer render, List<Material> mats)
	{
		Material[] arr = ArrayPoolEx<Material>.Create(mats.Count, true);
		for(int i = 0; i < mats.Count; i++)
		{
			arr[i] = mats[i];
		}

		render.sharedMaterials = arr;
		ArrayPoolEx<Material>.Recycle(arr);
		arr = null;
	}

    //GetComponentsEx
    public static List<Component> GetComponentsEx(this Component com, System.Type t)
    {
        List<Component> l = UnityListPool<Component>.Create();
        com.GetComponents(t, l);
        return l;
    }

    public static List<T> GetComponentsEx<T>(this Component com) where T : class
    {
        List<T> l = UnityListPool<T>.Create();
        com.GetComponents<T>(l);
        return l;
    }

    public static List<Component> GetComponentsEx(this GameObject com, System.Type t)
    {
        List<Component> l = UnityListPool<Component>.Create();
        com.GetComponents(t, l);
        return l;
    }

    public static List<T> GetComponentsEx<T>(this GameObject com) where T : class
    {
        List<T> l = UnityListPool<T>.Create();
        com.GetComponents<T>(l);
        return l;
    }



    //GetComponentsInChildrenEx
    public static List<Component> GetComponentsInChildrenEx(this Component com, System.Type t)
    {
        return GetComponentsInChildrenEx(com, t, false);
    }

    public static List<Component> GetComponentsInChildrenEx(this Component com, System.Type t, bool includeInactive)
    {
        List<Component> l3 = UnityListPool<Component>.Create();

        List<Component> l2 = UnityListPool<Component>.Create();
        List<Transform> l = com.GetTransformsInChildren(includeInactive);
        for (int i = 0; i < l.Count; i++)
        {
            l[i].GetComponents(t, l2);

            l3.AddRange(l2);
        }
        l.RecycleToListPool();
        l2.RecycleToListPool();

        return l3;
    }

    public static List<T> GetComponentsInChildrenEx<T>(this Component com) where T : class
    {
        return GetComponentsInChildrenEx<T>(com, false);
    }

    public static List<T> GetComponentsInChildrenEx<T>(this Component com, bool includeInactive) where T : class
    {
        List<T> l = UnityListPool<T>.Create();
        com.GetComponentsInChildren<T>(includeInactive, l);
        return l;
    }

    public static List<T> GetComponentsInChildrenEx<T>(this GameObject com) where T : class
    {
        return GetComponentsInChildrenEx<T>(com, false);
    }

    public static List<T> GetComponentsInChildrenEx<T>(this GameObject com, bool includeInactive) where T : class
    {
        List<T> l = UnityListPool<T>.Create();
        com.GetComponentsInChildren<T>(includeInactive, l);
        return l;
    }


    //GetComponentsInParentEx
    public static List<Component> GetComponentsInParentEx(this Component com, System.Type t)
    {
        return GetComponentsInParentEx(com, t, false);
    }

    public static List<Component> GetComponentsInParentEx(this Component com, System.Type t, bool includeInactive)
    {
        List<Component> l3 = UnityListPool<Component>.Create();

        List<Component> l2 = UnityListPool<Component>.Create();
        List<Transform> l = com.GetTransformsInParent(includeInactive);
        for (int i = 0; i < l.Count; i++)
        {
            l[i].GetComponents(t, l2);

            l3.AddRange(l2);
        }
        l.RecycleToListPool();
        l2.RecycleToListPool();

        return l3;
    }

    public static List<T> GetComponentsInParentEx<T>(this Component com) where T : class
    {
        return GetComponentsInParentEx<T>(com, false);
    }

    public static List<T> GetComponentsInParentEx<T>(this Component com, bool includeInactive) where T : class
    {
        List<T> l = UnityListPool<T>.Create();
        com.GetComponentsInParent<T>(includeInactive, l);
        return l;
    }

    public static List<T> GetComponentsInParentEx<T>(this GameObject com) where T : class
    {
        return GetComponentsInParentEx<T>(com, false);
    }

    public static List<T> GetComponentsInParentEx<T>(this GameObject com, bool includeInactive) where T : class
    {
        List<T> l = UnityListPool<T>.Create();
        com.GetComponentsInParent<T>(includeInactive, l);
        return l;
    }












    static public List<Transform> GetTransformsInChildren(this Component com)
    {
        return com.GetComponentsInChildrenEx<Transform>(false);
    }

    static public List<Transform> GetTransformsInChildren(this Component com, bool includeInactive)
    {
        return com.GetComponentsInChildrenEx<Transform>(includeInactive);
    }

    static public List<Transform> GetTransformsInChildren(this GameObject com)
    {
        return com.GetComponentsInChildrenEx<Transform>(false);
    }

    static public List<Transform> GetTransformsInChildren(this GameObject com, bool includeInactive)
    {
        return com.GetComponentsInChildrenEx<Transform>(includeInactive);
    }

    static public List<Renderer> GetRenderersInChildren(this Component com)
    {
        return com.GetComponentsInChildrenEx<Renderer>(false);
    }

    static public List<Renderer> GetRenderersInChildren(this Component com, bool includeInactive)
    {
        return com.GetComponentsInChildrenEx<Renderer>(includeInactive);
    }

    static public List<Renderer> GetRenderersInChildren(this GameObject com)
    {
        return com.GetComponentsInChildrenEx<Renderer>(false);
    }

    static public List<Renderer> GetRenderersInChildren(this GameObject com, bool includeInactive)
    {
        return com.GetComponentsInChildrenEx<Renderer>(includeInactive);
    }

    static public List<ParticleSystem> GetParticleSystemsInChildren(this Component com)
    {
        return com.GetComponentsInChildrenEx<ParticleSystem>(false);
    }

    static public List<ParticleSystem> GetParticleSystemsInChildren(this Component com, bool includeInactive)
    {
        return com.GetComponentsInChildrenEx<ParticleSystem>(includeInactive);
    }

    static public List<ParticleSystem> GetParticleSystemsInChildren(this GameObject com)
    {
        return com.GetComponentsInChildrenEx<ParticleSystem>(false);
    }

    static public List<ParticleSystem> GetParticleSystemsInChildren(this GameObject com, bool includeInactive)
    {
        return com.GetComponentsInChildrenEx<ParticleSystem>(includeInactive);
    }





    static public List<Transform> GetTransformsInParent(this Component com)
    {
        return com.GetComponentsInParentEx<Transform>(false);
    }

    static public List<Transform> GetTransformsInParent(this Component com, bool includeInactive)
    {
        return com.GetComponentsInParentEx<Transform>(includeInactive);
    }
}